package com.internetCafes.spms.web.customer.bizservice.impl.user;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.internetCafes.spms.common.utils.ShiroUtils;
import com.internetCafes.spms.common.utils.entity.page.PageItemDTO;
import com.internetCafes.spms.common.utils.entity.page.PageItemUtil;
import com.internetCafes.spms.common.utils.entity.page.PageItemVO;
import com.internetCafes.spms.core.exception.RRException;
import com.internetCafes.spms.core.exception.RRExceptionCodeEnum;
import com.internetCafes.spms.web.customer.bizservice.user.IEntUserInfoBizService;
import com.internetCafes.spms.web.customer.common.cont.CommonConst;
import com.internetCafes.spms.web.customer.common.cont.CustomerConst;
import com.internetCafes.spms.web.customer.common.cont.UserConst;
import com.internetCafes.spms.web.customer.common.util.UserInfoUtil;
import com.internetCafes.spms.web.customer.entity.customer.Customer;
import com.internetCafes.spms.web.customer.entity.user.EntUserInfo;
import com.internetCafes.spms.web.customer.model.area.EntAreaManagerPo;
import com.internetCafes.spms.web.customer.model.area.EntSaleAreaListDo;
import com.internetCafes.spms.web.customer.model.area.EntSaleAreaListPo;
import com.internetCafes.spms.web.customer.model.user.*;
import com.internetCafes.spms.web.customer.service.area.IAreaService;
import com.internetCafes.spms.web.customer.service.customer.ICustomerService;
import com.internetCafes.spms.web.customer.service.role.IRoleDeptDataAssoService;
import com.internetCafes.spms.web.customer.service.user.IEntUserInfoService;
import com.internetCafes.spms.web.sys.model.UserInfo;
import com.internetCafes.spms.web.sys.service.UserRoleInfoService;
import com.internetCafes.spms.web.tenant.common.TenantConst;
import com.sms.common.util.hutool.core.bean.BeanUtil;
import com.sms.common.util.hutool.core.util.ObjectUtil;
import com.sms.common.util.hutool.core.util.StrUtil;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class EntUserInfoBizServiceImpl implements IEntUserInfoBizService {

    @Autowired
    private IEntUserInfoService userInfoService;
    @Autowired
    private UserRoleInfoService userRoleInfoService;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private IAreaService areaService;
    @Autowired
    private IRoleDeptDataAssoService roleDeptDataAssoService;

    /**
     * 对通过id批量删除 进行校验
     *
     * @param idList id列表
     */
    @Override
    public EntUserDeleteVerifyRes verifyUserDeleteByIdList(List<Long> idList) {
        // 删除失败的用户下有多少成交企业、有多少成交人、多少意向客户、哪些区域销售、那些区域管理
        /*
           成交企业 x_customer表follow_user_id = userId typeId = 1 enterprise_flag = 1
           成交客户 x_customer表follow_user_id = userId typeId = 1
           意向客户 x_customer表follow_user_id = userId typeId = 2
           区域销售 x_area_sale表sale_id = userId
           区域管理 x_area_manager表manager_id = userId
         */
        // 获取所有的客户信息 根据followUserId
        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Customer::getFollowUserId, idList)
                .ne(Customer::getTypeId, CustomerConst.TypeEnum.GENERAL.getId());
        Map<Long, List<Customer>> customerListGroupByFollowUserId = customerService.list(queryWrapper)
                .stream()
                .collect(Collectors.groupingBy(Customer::getFollowUserId));

        // 获取销售区域信息
        Map<Long, List<EntSaleAreaListPo>> saleAreaListGroupBySaleId = areaService.saleAreaListPo(new EntSaleAreaListDo().setSaleIdList(idList))
                .stream().collect(Collectors.groupingBy(EntSaleAreaListPo::getSaleId));

        // 获取管理区域信息
        Map<Long, List<EntAreaManagerPo>> managerAreaGroupByManagerId = areaService.getAreaInfoByManagerIdList(idList)
                .stream().collect(Collectors.groupingBy(EntAreaManagerPo::getManagerId));

        List<EntUserDeleteVerifyRes.UserDataCount> userDataCountList = new ArrayList<>();
        for (Long userId : idList) {
            // 封装客户相关信息
            int dealEnterpriseAmount = 0, dealCustomerAmount = 0, intentionAmount = 0;
            List<EntAreaManagerPo> managerAreaList = null;
            List<EntSaleAreaListPo> saleAreaList = null;
            boolean deleteAble = false;
            if (customerListGroupByFollowUserId.containsKey(userId)) {
                deleteAble = true;
                List<Customer> customerPoList = customerListGroupByFollowUserId.get(userId);
                for (Customer customerPo : customerPoList) {
                    if (CustomerConst.TypeEnum.DEAL.getId().equals(customerPo.getTypeId())
                            && CommonConst.FlagEnum.IS.getId().equals(customerPo.getEnterpriseFlag())) {
                        dealEnterpriseAmount++;
                    }
                    if (CustomerConst.TypeEnum.DEAL.getId().equals(customerPo.getTypeId())
                            && CommonConst.FlagEnum.NOT.getId().equals(customerPo.getEnterpriseFlag())) {
                        dealCustomerAmount++;
                    }
                    if (CustomerConst.TypeEnum.INTENTION.getId().equals(customerPo.getTypeId())) {
                        intentionAmount++;
                    }
                }
            }

            // 封装管理区域
            if (managerAreaGroupByManagerId.containsKey(userId)) {
                deleteAble = true;
                managerAreaList = managerAreaGroupByManagerId.get(userId);
            }
            // 封装销售区域
            if (saleAreaListGroupBySaleId.containsKey(userId)) {
                deleteAble = true;
                saleAreaList = saleAreaListGroupBySaleId.get(userId);
            }

            if (deleteAble) {
                userDataCountList.add(new EntUserDeleteVerifyRes.UserDataCount(userId, dealEnterpriseAmount, dealCustomerAmount, intentionAmount, saleAreaList, managerAreaList));
            }
        }

        return new EntUserDeleteVerifyRes(CollectionUtil.isEmpty(userDataCountList), userDataCountList);
    }

    @Override
    public List<EntUserListRes> userList(EntUserListReq req) {
        EntUserDetailListDo listDo = new EntUserDetailListDo();
        BeanUtil.copyProperties(req, listDo);
        UserInfo userEntity = ShiroUtils.getUserEntity();
        if (!UserInfoUtil.entSuperAdminJudge(userEntity)
                && UserInfoUtil.managerJudge(userEntity)) {
            listDo.setManagerId(ShiroUtils.getUserId());
        }
        List<EntUserDetailListPo> userList = userInfoService.userDetailList(listDo);

        return userList
                .stream()
                .map(po -> new EntUserListRes(po.getId(), po.getNickName(), po.getName()))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean resetUserPassword(Long id) {
        EntUserInfo userInfo = userInfoService.getById(id);
        if (ObjectUtil.isNull(userInfo)) {
            throw new RRException(RRExceptionCodeEnum.DATA_NOT_EXIST);
        }

        EntUserInfo userInfoDo = new EntUserInfo().setId(id);

        String userPassword;
        if (userInfo.getName().length() < UserConst.USER_DEFAULT_PASSWORD_LENGTH) {
            userPassword = userInfo.getName();
        } else {
            userPassword = userInfo.getName().substring(userInfo.getName().length() - UserConst.USER_DEFAULT_PASSWORD_LENGTH);
        }

        userInfoDo.setPassword(new Sha256Hash(userPassword, userInfo.getSalt()).toHex());

        return userInfoService.updateById(userInfoDo);
    }

    @Override
    @Transactional
    public boolean userDelete(List<Long> idList) {
        // 如果有关联数据（成交客户、意向客户、区域销售），提示该账号下还有关联数据，无法删除。
        /*Integer userInfoExtendAmount = userInfoService.countUserExtendInfoByIds(idList);
        if (userInfoExtendAmount > BigDecimal.ROUND_UP) {
            throw new RRException(RRExceptionCodeEnum.USER_HAS_EXTEND_INFO);
        }*/
        EntUserDeleteVerifyRes entUserDeleteVerifyRes = verifyUserDeleteByIdList(idList);
        if (!entUserDeleteVerifyRes.isDeleteAble()) {
            throw new RRException(RRExceptionCodeEnum.USER_DELETE_FAIL_AS_HAVE_EXTEND_DATA);
        }

        // 删除角色绑定信息
        userRoleInfoService.deleteByUserIdList(idList);

        return userInfoService.removeByIds(idList);
    }

    @Override
    public boolean userInfoUpdate(EntUserUpdateReq req) {
        if (ObjectUtil.isNull(req.getId()) || ObjectUtil.isNull(req.getRoleId())
                || StrUtil.isBlank(req.getNickName()) || StrUtil.isBlank(req.getName())
                || StrUtil.isBlank(req.getMobile()) || ObjectUtil.isNull(req.getStatus())
        ) {
            throw new RRException(RRExceptionCodeEnum.PARAM_ERROR);
        }

        EntUserInfo userInfo = userInfoService.getById(req.getId());
        if (ObjectUtil.isNull(userInfo)) {
            throw new RRException(RRExceptionCodeEnum.DATA_NOT_EXIST);
        }

        EntUserInfo userInfoDo = new EntUserInfo();
        BeanUtils.copyProperties(req, userInfoDo);

        if (!userInfoService.updateById(userInfoDo)) {
            return false;
        }

        // 重新绑定用户信息
        userRoleInfoService.saveOrUpdate(userInfoDo.getId(), Collections.singletonList(req.getRoleId()));
        return true;
    }

    @Override
    public PageItemVO<EntUserPagingRes> userInfoPaging(PageItemDTO<EntUserPagingReq> req) {
        Page<EntUserInfo> pageDo = new Page<>(req.getPageNum(), req.getPageSize());
        UserInfo userEntity = ShiroUtils.getUserEntity();

        EntUserPagingReq conditions = req.getConditions();
        QueryWrapper<EntUserInfo> queryWrapper = new QueryWrapper<>();
        UserInfoDo userInfoDo = new UserInfoDo();
        BeanUtil.copyProperties(conditions, userInfoDo);
        userInfoDo.setTenantId(userEntity.getDeptId());

        /*
         * 如果不是管理员，过滤展示部门下的人员的数据
         */
        if (!UserInfoUtil.entSuperAdminJudge(userEntity) && !TenantConst.TENANT_DEPT_ROOT_PARENT_ID.equals(userEntity.getTenantDeptId())) {
            List<Long> deptIdList = new ArrayList<>();
            deptIdList.add(-1L);
            List<Long> authorizationDeptIdList = roleDeptDataAssoService.listDeptIdAuthorAndUserDeptUnder(userEntity);
            if (CollectionUtil.isNotEmpty(authorizationDeptIdList)) {
                deptIdList.addAll(authorizationDeptIdList);
            }
            userInfoDo.setDeptIdList(deptIdList);
        }

        PageItemUtil.order(req, queryWrapper);
        Page<EntUserInfoPo> pagingPo = userInfoService.poPaging(pageDo, userInfoDo);
        PageItemVO<EntUserPagingRes> pagingRes = PageItemUtil.toPageItemVO(pagingPo, new PageItemVO<>());
        pagingRes.setRecords(
                pagingPo.getRecords()
                        .stream()
                        .map(po -> {
                            EntUserPagingRes res = new EntUserPagingRes();
                            BeanUtils.copyProperties(po, res);
                            return res;
                        })
                        .collect(Collectors.toList())
        );
        return pagingRes;
    }
}
